package com.xyj.data.data_controller_demo.dataFilter.util;


import com.xyj.data.data_controller_demo.dataFilter.annotation.Allow;
import com.xyj.data.data_controller_demo.dataFilter.modle.FunctionCol;
import lombok.SneakyThrows;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author xyj
 * @date 2023/12/14
 */
@Component
public class FunctionUtil {

    public final static String PLACEHOLDER_STR = "B";


    /**
     * 获取允许字段列表
     *
     * @param aClass 待获取允许字段的类
     * @return 允许字段列表
     */
    public List<FunctionCol> getAllowFields(Class<?> aClass) {
        // 获取类的声明字段
        Field[] fields = aClass.getDeclaredFields();
        ArrayList<FunctionCol> result = new ArrayList<>();
        for (Field f : fields) {
            // 设置字段可访问
            f.setAccessible(true);
            // 获取字段的泛型类型
            Type genericType = f.getGenericType();
            // 获取字段名称
            String name = f.getName();
            // 获取字段的Allow注解
            Allow annotation = f.getAnnotation(Allow.class);
            if (annotation != null) {
                // 创建FunctionCol对象
                FunctionCol functionCol = new FunctionCol();
                // 设置列名称
                functionCol.setColName(name);
                // 设置列名称描述
                functionCol.setColNameDesc(annotation.value());
                // 设置列类型
                functionCol.setColType(genericType.getTypeName());
                // 将FunctionCol对象添加到结果列表
                result.add(functionCol);
            }
        }
        // 返回允许字段列表
        return result;
    }


    /**
     * 校验字段是否为空
     *
     * @param elStr     字段名称
     * @param variables 变量集合
     * @return 如果字段为空则返回false，否则返回true
     */
    public Boolean checkFiled(String elStr, Map<String, Object> variables) {
        // 创建评估上下文对象
        EvaluationContext context = new StandardEvaluationContext();
        // 将变量集合中的变量设置到评估上下文中
        variables.forEach(context::setVariable);
        // 创建表达式解析器对象
        ExpressionParser parser = new SpelExpressionParser();
        // 解析表达式并获取值
        return parser.parseExpression(elStr).getValue(context, Boolean.class);
    }


    /**
     * 获取对象指定字段的值
     *
     * @param name 字段名
     * @param obj  对象实例
     * @return 字段的值
     */
    @SneakyThrows
    public Object getFieldValueByName(String name, Object obj) {
        Class<?> aClass = obj.getClass();
        Field declaredField = aClass.getDeclaredField(name);
        declaredField.setAccessible(true);
        return declaredField.get(obj);
    }

}
